package com.rq.base.ui;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;


import com.rq.base.BASE;
import com.rq.base.R;
import com.rq.base.net.RequestType;
import com.rq.base.reflect.activity.Act_onMultiWindowModeChanged;
import com.rq.base.reflect.activity.Act_onLowMemory;
import com.rq.base.reflect.activity.Act_onNewIntent;
import com.rq.base.reflect.activity.Act_onTrimMemory;
import com.rq.base.reflect.activity.Act_onWindowFocusChanged;
import com.rq.base.ui.common.CommonLandscapeActivity;
import com.rq.base.ui.common.CommonPortraitActivity;
import com.rq.base.ui.common.FullScreenLandscapeActivity;
import com.rq.base.ui.common.FullScreenPortraitActivity;
import com.rq.base.ui.common.TransLandscapeActivity;
import com.rq.base.ui.common.TransPortraitActivity;
import com.rq.base.ui.impl.BaseView;
import com.rq.base.util.AppUtils;
import com.rq.base.util.LOG;
import com.rq.base.util.ToastUtil;
//import com.smarx.notchlib.NotchScreenManager;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import static com.rq.base.BASE.isDebug;
import static com.rq.base.ui.BaseController.TAG_NAME;
import static com.rq.base.ui.BaseController.TAG_PASS;
import static com.rq.base.ui.BaseController.TAG_PASS_DATA_SIZE;

public class BaseActivity<P extends BaseController> extends ActivityLife implements BaseView,
        DialogInterface.OnCancelListener {

    public static String TAG_OPEN_FOR = "open.for";
    public static String TAG_OPEN_CODE = "open.code";
    private static Set<String> hasStartClass = new HashSet<>();

    public static void open(Context controller, Class clazz, Serializable... pass) {
        if (BaseController.class.isAssignableFrom(clazz)) {
            LOG.e("BaseActivity", "62.open:");
            if (controller != null) {
                BaseController target = getController(clazz);
                if (target == null) {
                    ToastUtil.show("启动异常: " + clazz.getSimpleName());
                    return;
                }
                Intent intent;
                intent = getInnerIntent(target, clazz, pass);
                controller.startActivity(intent);
            }
        } else {
            LOG.e("BaseActivity", "74.open:");
            Intent intent = new Intent(controller, clazz);
            controller.startActivity(data2Intent(intent, pass));
        }
    }

    public static void skip(BaseController controller, Class clazz, Serializable... pass) {
        if (controller != null) {
            open(controller, clazz, pass);
            controller.finish();
        }
    }

    public static void openFor(BaseController controller, Class clazz, Serializable... pass) {
        if (clazz != null) {
            if (hasStartClass.contains(clazz.getSimpleName())) {
                LOG.e("BaseActivity", "openFor.启动跳过重复:" + clazz.getSimpleName());
                return;
            }
            hasStartClass.add(clazz.getSimpleName());
        }
        if (BaseController.class.isAssignableFrom(clazz)) {
            if (controller != null) {
                BaseController target = getController(clazz);
                Intent intent = getInnerIntent(target, clazz, pass);
                intent.putExtra(TAG_OPEN_FOR, true);
                controller.startActivityForResult(intent);
            }
        } else {
            Intent intent = new Intent(controller.getContext(), clazz);
            controller.startActivityForResult(data2Intent(intent, pass));
        }

    }

    public static void openWith(BaseController controller, int requestCode, Class clazz, Serializable... pass) {
        if (clazz != null) {
            if (hasStartClass.contains(clazz.getSimpleName())) {
                LOG.e("BaseActivity", "openWith.启动跳过重复:" + clazz.getSimpleName());
                return;
            }
            hasStartClass.add(clazz.getSimpleName());
        }
        if (BaseController.class.isAssignableFrom(clazz)) {
            if (controller != null) {
                BaseController target = getController(clazz, controller.getClass().getSimpleName());
                Intent intent = getInnerIntent(target, clazz, pass);
                LOG.d("BaseController", "onResultOK.openWith>" + requestCode);
                intent.putExtra(TAG_OPEN_FOR, true);
                intent.putExtra(TAG_OPEN_CODE, requestCode);
                controller.startActivityForResult(intent, requestCode);
            }
        } else {
            Intent intent = new Intent(controller.getContext(), clazz);
            controller.startActivityForResult(data2Intent(intent, pass), requestCode);
        }
    }

    public static void open(BaseController controller, Class clazz, Serializable... pass) {
        if (BaseController.class.isAssignableFrom(clazz)) {
            BaseController target = getController(clazz, controller.getClass()
                    .getSimpleName());
            if (target == null) {
                LOG.e("BaseActivity", "open.147:" + clazz.getSimpleName());
                ToastUtil.show("启动异常: " + clazz.getSimpleName());
                return;
            }
            LOG.e("BaseActivity", "open.151:" + clazz.getSimpleName());
            Intent intent;
            intent = getInnerIntent(target, clazz, pass);
            controller.startActivity(intent);
        } else {
            Intent intent = new Intent(controller.getContext(), clazz);
            controller.startActivity(data2Intent(intent, pass));
        }

    }

    @SuppressLint("RestrictedApi")
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (mPresenter != null && mPresenter.dispatchKeyEvent(event)) {
            return true;
        }
        return super.dispatchKeyEvent(event);
    }


    @NonNull
    public static Intent getOutIntent(Context context, Class<?> clazz, Serializable... pass) {
        Intent intent = new Intent(context, CommonPortraitActivity.class);
        intent.putExtra(TAG_NAME, clazz);
        return data2Intent(intent, pass);
    }

    /**
     * @param clazz 目标控制器
     * @param pass  传递数据
     * @see BaseController#getPass(int, Intent[])
     */
    @NonNull
    public static Intent getInnerIntent(BaseController target, Class<?> clazz, Serializable... pass) {
        Intent intent;
        if (!target.showStatusBar()) {
            if (BASE.getLockScreenOrientation() == 1) {
                intent = new Intent(BASE.getCxt(), FullScreenPortraitActivity.class);
            } else if (BASE.getLockScreenOrientation() == 2) {
                intent = new Intent(BASE.getCxt(), FullScreenLandscapeActivity.class);
            } else {
                intent = new Intent(BASE.getCxt(), FullScreenPortraitActivity.class);
            }
        } else if (target.isTransparentActivity()) {
            if (BASE.getLockScreenOrientation() == 1) {
                intent = new Intent(BASE.getCxt(), TransPortraitActivity.class);
            } else if (BASE.getLockScreenOrientation() == 2) {
                intent = new Intent(BASE.getCxt(), TransLandscapeActivity.class);
            } else {
                intent = new Intent(BASE.getCxt(), TransPortraitActivity.class);
            }
        } else {
            if (BASE.getLockScreenOrientation() == 1) {
                intent = new Intent(BASE.getCxt(), CommonPortraitActivity.class);
            } else if (BASE.getLockScreenOrientation() == 2) {
                intent = new Intent(BASE.getCxt(), CommonLandscapeActivity.class);
            } else {
                intent = new Intent(BASE.getCxt(), CommonPortraitActivity.class);
            }
        }
        intent.putExtra(TAG_NAME, clazz);
        intent.setFlags(target.getActivityFlag());
        if (isDebug()) {
            for (int i = 0; i < pass.length; i++) {
                LOG.bean(clazz.getSimpleName() + ".PASS." + i, pass[i]);
            }
        }
        return data2Intent(intent, pass);
    }

    public static Intent data2Intent(Intent intent, Serializable... pass) {
        if (pass != null) {
            for (int i = 0; i < pass.length; i++) {
                intent.putExtra(TAG_PASS + i, pass[i]);
            }
            intent.putExtra(TAG_PASS_DATA_SIZE, pass.length);
        }
        return intent;
    }

    public static void reStart(BaseController controller, Class<? extends BaseController> clazz) {
        Intent intent = BaseActivity.getInnerIntent(controller, clazz);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        controller.getActivity().startActivity(intent);
    }

    public static <P extends BaseController> P getController(Class<P> clazz, Object... objects) {
        if (clazz == null) return null;
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            LOG.showUserWhere(objects);
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            LOG.showUserWhere(objects);
            e.printStackTrace();
        } catch (ClassCastException e) {
            LOG.showUserWhere(objects);
            e.printStackTrace();
        } catch (NullPointerException e) {
            LOG.showUserWhere(objects);
            e.printStackTrace();
        }
        return null;
    }

    protected P mPresenter;
    View root;
    boolean isFirstOnResume = true;
    public static String lastShowCon = null;

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LOG.e("BaseActivity", this.getClass().getSimpleName() + ".onConfigurationChanged.160:");
        initView(oldBundle);
    }

    private Bundle oldBundle;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
//        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
//            boolean result = fixOrientation();
//        }
//        ActivityHook.hookOrientation(this);//hook，绕过检查
        super.onCreate(savedInstanceState);
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());
        builder.detectFileUriExposure();
//        implementation 'com.github.smarxpan:NotchScreenTool:0.0.1'
//        NotchScreenManager.getInstance().setDisplayInNotch(this);
        this.oldBundle = savedInstanceState;
        try {
            initView(savedInstanceState);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setNavigationBarColor(Color.WHITE);
        }
//        AndroidBug5497Workaround.assistActivity(this);
    }

    public void reloadView() {
        this.initView(oldBundle);
    }

    private void initView(Bundle savedInstanceState) {
        Class<P> clazz = (Class<P>) getIntent().getSerializableExtra(TAG_NAME);
        mPresenter = getController(clazz, this.getClass().getSimpleName());
        if (mPresenter == null) {
            mPresenter = getController(this, 0);
        }
        if (mPresenter != null) {
            mPresenter.setActivity(this);
            final LayoutInflater inflater = LayoutInflater.from(this);
            root = mPresenter.inflateRootView(inflater);
            if (!mPresenter.isTransparentActivity() && root != null && root.getBackground() == null) {
                root.setBackgroundResource(R.color.all_background);
            }
            LOG.e("BaseActivity", "308:" + (root != null));
            if (root != null) setContentView(root);
            try {
                mPresenter.onViewCreated(savedInstanceState);
            } catch (Exception e) {
                e.printStackTrace();
                LOG.e("BaseActivity", "界面显示异常.:" + mPresenter.getClass().getSimpleName());
            }
            LOG.e("BaseActivity", "312:" + mPresenter);
//
//    此方法暂未确定添加原因 保留代码 @BaseController.refuseStatusBar()
//            mPresenter.refuseStatusBar();
            if (findViewById(R.id.common_status_bar) != null) {
                ViewGroup.LayoutParams params = findViewById(R.id.common_status_bar).getLayoutParams();
                params.height = AppUtils.getStatusBarHeight();
                params.width = ViewGroup.LayoutParams.MATCH_PARENT;
                findViewById(R.id.common_status_bar).setLayoutParams(params);
            }
            if (mPresenter.isTranslucent()) {
                this.getWindow().getDecorView()
                        .setBackgroundColor(getResources().getColor(R.color.transparent_pop));
            }
            LOG.e("BaseActivity", "324:");
        }
    }

    public View getRootView() {
        return root;
    }

    public Object getPass(int position) {
        LOG.e("BaseActivity", "getPass.251:TAG_PASS");
        return getIntent().getSerializableExtra(TAG_PASS + position);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (mPresenter != null) {
            LOG.e("BaseActivity", "onActivityResult.259:");
            if (mPresenter.onActivityResult(requestCode, resultCode, data)) {
                return;
            }
        }
        try {
            List<Fragment> fragments = getSupportFragmentManager().getFragments();
            LOG.e("BaseActivity", "onActivityResult.264:" + fragments.size());
            for (Fragment fragment : fragments) {
                if (fragment.isVisible()) {
                    fragment.onActivityResult(requestCode, resultCode, data);
                } else {
                    LOG.e("BaseActivity", "onActivityResult.269:");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mPresenter != null) {
            lastShowCon = mPresenter.getClass().getSimpleName();
            mPresenter.onControllerResume();
            mPresenter.onActivityResume();
            CtrWatcher.get().addActivityController(mPresenter);
            CtrWatcher2.get().addActivityController(mPresenter);
            LOG.i("BaseActivity", mPresenter.getClass().getSimpleName() + " LINE:onResume");
        }
        LOG.i("BaseActivity", "isFirstOnResume = " + isFirstOnResume);
        if (isFirstOnResume) {
            isFirstOnResume = false;
        } else {
            CtrWatcher.get().notifyFragmentOnResume();
            CtrWatcher2.get().notifyFragmentOnResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mPresenter != null) {
            LOG.i("BaseActivity", mPresenter.getClass().getSimpleName() + " LINE:onControllerPause");
            //            CtrWatcher.get().removerActivityController(mPresenter);
            mPresenter.onControllerPause();
            mPresenter.onActivityPause();
            CtrWatcher.get().removerActivityController(mPresenter);
            CtrWatcher2.get().removerActivityController(mPresenter);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LOG.e("BaseActivity", "onDestroy:" + this.mPresenter);
        if (this.mPresenter != null) {
            String rmvName = this.mPresenter.getClass().getSimpleName();
            hasStartClass.remove(rmvName);
            CtrWatcher.get().removeWatch(this.mPresenter);
            CtrWatcher2.get().removeWatch(this.mPresenter);
            this.mPresenter.onActivityDestroy();
            this.mPresenter = null;
        }
    }

    //反射获取当前Presenter对象
    protected P getController(Object o, int i) {
        try {
//            P back = getController((Class<P>) ((ParameterizedType) (o.getClass().getGenericSuperclass()))
//                    .getActualTypeArguments()[i], this.getClass().getSimpleName());

            P back = getController((Class<P>) ((ParameterizedType) (o.getClass().getGenericSuperclass()))
                    .getActualTypeArguments()[i], this);

            back.setActivity(BaseActivity.this);
            return back;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void onBackPressed() {
        if (mPresenter != null && mPresenter.interruptBack()) {
            return;
        }
        super.onBackPressed();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mPresenter != null) {
            if (mPresenter.onKeyDown(keyCode, event)) {
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public <T> void handleFailResponse(T baseBean) {

    }

    protected LoadingDialog progressDialog;

    @Override
    public void showLoading(String... msg) {
        if (progressDialog == null) {
            progressDialog = new LoadingDialog(this);
//            progressDialog.setCancelable(false);
            progressDialog.setOnCancelListener(this);
        }
        if (msg.length > 0) {
            progressDialog.setTitle(msg[0]);
        }
        try {
            if (!progressDialog.isShowing()) {
                progressDialog.show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void dismissLoading() {
        if (progressDialog != null) {
            try {
                progressDialog.dismiss();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public final Activity getContext() {
        return this;
    }

    @Override
    public <T> void onResponseSucceed(@NonNull RequestType type, T data) {

    }

    @Override
    public <T> void onResponseError(@NonNull RequestType type, @NonNull T data) {

    }

    @Override
    public void onConnectError(@NonNull RequestType type) {

    }

    @Override
    public void onCancel(DialogInterface dialog) {
        if (mPresenter != null) {
            mPresenter.onProgressCancel(dialog);
        }
    }

    public boolean isShowProgress() {
        return progressDialog != null && progressDialog.isShowing();
    }

//    public static <P extends BaseController> void openLogin(Context controller, Class<P> clazz, Serializable... pass) {
//        if (controller != null) {
//            BaseController target = (BaseController) getController(clazz, controller.getClass()
//                    .getSimpleName());
//            if (target == null) {
//                ToastUtil.show("启动异常: " + clazz.getSimpleName());
//                return;
//            }
//            Intent intent;
//            intent = getInnerIntent(target, clazz, pass);
//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            controller.startActivity(intent);
//        }
//    }

    @Override
    protected final Object getCtr() {
        return mPresenter;
    }
}
